home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / aminet / os20 / wb / uhr101.lha / Uhr.c < prev    next >
C/C++ Source or Header  |  1992-09-21  |  16KB  |  473 lines

  1. /*
  2.  *  Uhr.c
  3.  *
  4.  *  Author: Stefan Sticht
  5.  *
  6.  *  Copyright: source is public domain, no copyright
  7.  *
  8.  *  Version history:
  9.  *
  10.  *  V0.01   initial release
  11.  *  V0.02   using now cback.o
  12.  *  V0.03   RMBTRAP flag set
  13.  *  V0.04   added LockIBase before looking at IntuitionBase
  14.  *          (thanks to Holger Gzella for bug report),
  15.  *          added screen title
  16.  *  V0.05   structure for timerequest is now in MEMF_PUBLIC
  17.  *          (thanks to Holger Gzella)
  18.  *          now using CreateMsgPort() from exec.library instead of CreatePort() from amiga.lib
  19.  *  V0.06   changed LockPubScreen("Workbench") to LockPubScreen(NULL)
  20.  *          now using CreateIORequest(); using WaitIO() instead of Wait() after AbortIO()
  21.  *          removed LockIBase(), redefined SAS/C chkabort() to prevent CTRL/C trapping
  22.  *  V0.07 14 Sep 1991 small changes to reduce size
  23.  *  V1.00 13 May 1992 mow uses locale.library's FormatDate()
  24.  *  V1.01 19 Sep 1992 small changes, reduced size
  25.  */
  26.  
  27. #define VERSION "1.01"
  28.  
  29. #include <stdarg.h>
  30. #include <stdlib.h>
  31. #include <string.h>
  32. #include <devices/timer.h>
  33. #include <exec/memory.h>
  34. #include <intuition/intuitionbase.h>
  35. #include <libraries/locale.h>
  36. #include <workbench/icon.h>
  37. #include <workbench/startup.h>
  38. #include <clib/alib_protos.h>
  39. #include <clib/dos_protos.h>
  40. #include <clib/exec_protos.h>
  41. #include <clib/graphics_protos.h>
  42. #include <clib/icon_protos.h>
  43. #include <clib/intuition_protos.h>
  44. #include <clib/locale_protos.h>
  45. #include <pragmas/dos_pragmas.h>
  46. #include <pragmas/exec_pragmas.h>
  47. #include <pragmas/graphics_pragmas.h>
  48. #include <pragmas/icon_pragmas.h>
  49. #include <pragmas/intuition_pragmas.h>
  50. #include <pragmas/locale_pragmas.h>
  51.  
  52. /*
  53.  *  prototypes
  54.  */
  55. long request(char *title, char *gadgets, char *text, ...);
  56. struct Library __regargs *myopenlibrary(char *name, unsigned long version);
  57. void getmessages(struct Window *win);
  58. void __saveds __asm putcharfunc(register __a0 struct Hook *h, register __a2 void *object, register __a1 char c);
  59.  
  60. /*
  61.  *  global data
  62.  */
  63. #define PROGRAMTITLE    "Uhr"
  64. #define TITLE           PROGRAMTITLE " " VERSION " © Stefan Sticht"
  65.  
  66. #define MSG_ERROR_LIBRARY   "Couldn't open %s (V%ld)!"
  67. #define MSG_ERROR_OPENPORT  "Couldn't open message port!"
  68. #define MSG_ATTENTION       PROGRAMTITLE ":"
  69. #define RESUME_GADGETS      "Resume"
  70. #define RETRY_GADGETS       "Retry|Cancel"
  71.  
  72. #ifdef __SASC
  73. extern struct WBStartup *WBenchMsg;
  74. extern struct Library *DOSBase;
  75. extern struct Library *SysBase;
  76. int CXBRK(void) {return(0);}     /* disable Ctrl-C detect */
  77. int chkabort(void) {return(0);}
  78. #endif
  79.  
  80. #define BUFFERSIZE 100
  81. char buffer[BUFFERSIZE];
  82.  
  83. struct Hook putcharhook = {
  84.     {NULL, NULL},
  85.     (ULONG)putcharfunc,
  86.     NULL,
  87.     buffer
  88.     };
  89.  
  90. #define TITLE_OFFSET 7
  91. static char version[] ="\0$VER: " TITLE;
  92.  
  93. short bufferpos;
  94. struct DateStamp datestamp;
  95. struct Library *GfxBase;
  96. struct Library *LocaleBase;
  97. struct Locale *locale;
  98. struct IntuitionBase *IntuitionBase;
  99. struct timerequest *timereq;
  100. struct MsgPort *timerport;
  101.  
  102. unsigned long updateseconds = 1;
  103. unsigned long updatemicros  = 0;
  104. long priority = -1;
  105.  
  106. #define OPTION_FORMAT           "FORMAT"
  107. #define OPTION_UPDATESECONDS    "UPDATESECONDS"
  108. #define OPTION_UPDATEMICROS     "UPDATEMICROS"
  109. #define OPTION_LEFT             "LEFT"
  110. #define OPTION_TOP              "TOP"
  111. #define OPTION_WINDOWTOFRONT    "WINDOWTOFRONT"
  112. #define OPTION_PRIORITY         "PRIORITY"
  113. #define OPTION_PUBSCREEN        "PUBSCREEN"
  114. #define TEMPLATE OPTION_FORMAT "/K," "S=" OPTION_UPDATESECONDS "/K/N," "M=" OPTION_UPDATEMICROS "/K/N,"\
  115.                  OPTION_LEFT "/K/N," OPTION_TOP "/K/N," "WTF=" OPTION_WINDOWTOFRONT "/S,"\
  116.                  "PRI=" OPTION_PRIORITY "/K/N," OPTION_PUBSCREEN "/K"
  117. #define OPTN_FORMAT             0
  118. #define OPTN_UPDATESECONDS      1
  119. #define OPTN_UPDATEMICROS       2
  120. #define OPTN_LEFT               3
  121. #define OPTN_TOP                4
  122. #define OPTN_WINDOWTOFRONT      5
  123. #define OPTN_PRIORITY           6
  124. #define OPTN_PUBSCREEN          7
  125. #define OPTN_COUNT              8
  126. long options[OPTN_COUNT];
  127.  
  128. #define FORMAT          (options[OPTN_FORMAT])
  129. #define WINDOWTOFRONT   (options[OPTN_WINDOWTOFRONT])
  130. #define PUBSCREEN       (options[OPTN_PUBSCREEN])
  131.  
  132. /*
  133.  *  functions
  134.  */
  135.  
  136. /*
  137.  *  request(): a glue routine to EasyRequest as simple as printf plus
  138.  *             titlestring, gadgettexts
  139.  *
  140.  *  Input: char *title:         pointer to the title of the requester
  141.  *         char *gadgets:       pointer to gadgettext
  142.  *         char *text:          text displayed in requester
  143.  *
  144.  *  Result: same as EasyrequestArgs()
  145.  *
  146.  * !!! for more info see EasyRequestArgs() in Autodocs/intuition.doc !!!
  147.  */
  148. long request(char *title, char *gadgets, char *text, ...)
  149. {
  150.     /*
  151.      *  structure textreq only needed in this function, so hide it here
  152.      *  must be static, in order to be initialized only once
  153.      */
  154.     long rc = 0;
  155.     struct EasyStruct textreq = {
  156.         sizeof (struct EasyStruct), /* ULONG es_StructSize      */
  157.         0l,                         /* ULONG es_Flags           */
  158.         NULL,                       /* UBYTE *es_Title          */
  159.         NULL,                       /* UBYTE *es_TextFormat     */
  160.         NULL,                       /* UBYTE *es_GadgetFormat   */
  161.         };
  162.     struct Process *process;
  163.     struct Window *win;
  164.     va_list ap;
  165.  
  166.     /*
  167.      *  get start of variable arguments
  168.      */
  169.     va_start(ap, text);
  170.  
  171.     if (process = (struct Process *)FindTask(NULL)) {
  172.         if ((long)(win = process->pr_WindowPtr) != -1) {
  173.  
  174.             /*
  175.              *  update textreq
  176.              */
  177.             textreq.es_Title = (UBYTE *)title;
  178.             textreq.es_TextFormat = (UBYTE *)text;
  179.             textreq.es_GadgetFormat = (UBYTE *)gadgets;
  180.  
  181.             rc = EasyRequestArgs(win, &textreq, NULL, ap);
  182.  
  183.             }
  184.  
  185.         }
  186.  
  187.     va_end(ap);
  188.  
  189.     return(rc);
  190. }
  191.  
  192. /*
  193.  *  myopenlibrary(): same as OpenLibrary(), but opens a retry-requester
  194.  *                   if OpenLibrary() fails, to give the user a chance to
  195.  *                   copy the library to libs: and retry
  196.  *                   requires request(), see above
  197.  */
  198. struct Library __regargs *myopenlibrary(char *name, unsigned long version)
  199. {
  200.     struct Library *libptr;
  201.     long ok = TRUE;
  202.  
  203.     do {
  204.         if (!(libptr = OpenLibrary((UBYTE *)name, version))) {
  205.             ok = request(MSG_ATTENTION, RETRY_GADGETS, MSG_ERROR_LIBRARY, name, version);
  206.             }
  207.         } while (!libptr && ok);
  208.  
  209.     return(libptr);
  210. }
  211.  
  212. void _main(char *line)
  213. {
  214.     long rc = RETURN_FAIL;
  215.     struct DiskObject *diskobj = NULL;
  216.     struct Library *IconBase = NULL;
  217.     struct RDArgs *args = NULL;
  218.     struct Screen *scr;
  219.     struct Task *mytask;
  220.     struct Window *win;
  221.     char startpri;
  222.     #define WIDTH_OF_CLOSE_GADGET 20
  223.     #define WIDTH_OF_DEPTH_GADGET 23
  224.     #define P_WA_Left       0
  225.     #define P_WA_Top        1
  226.     #define P_WA_Width      2
  227.     #define P_WA_Height     3
  228.     #define P_WA_PubScreen  6
  229.     static struct TagItem mywindowtags[] = {
  230.         WA_Left,        0l,
  231.         WA_Top,         0l,
  232.         WA_Width,       0l,
  233.         WA_Height,      0l,
  234.         WA_IDCMP,       IDCMP_CLOSEWINDOW,
  235.         WA_Flags,       WFLG_DRAGBAR | WFLG_CLOSEGADGET | WFLG_SMART_REFRESH | WFLG_RMBTRAP,
  236.         WA_PubScreen,   0l,
  237.         WA_ScreenTitle, (ULONG)&version[TITLE_OFFSET],
  238.         TAG_END
  239.         };
  240.  
  241.     if (IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 37l)) {
  242.  
  243.         unsigned long left = -1;
  244.         unsigned long top = -1;
  245.  
  246.         if (!WBenchMsg) {
  247.             /*
  248.              *  started from Shell
  249.              *
  250.              *  change name of program
  251.              */
  252.             SetProgramName(PROGRAMTITLE);
  253.             /*
  254.              *  display banner
  255.              */
  256.             PutStr(&version[TITLE_OFFSET]); PutStr("\n");
  257.             /*
  258.              *  parse command line
  259.              */
  260.             if (args = ReadArgs((UBYTE *)TEMPLATE, options, NULL)) {
  261.                 if (options[OPTN_UPDATESECONDS]) updateseconds = *((long *)options[OPTN_UPDATESECONDS]);
  262.                 if (options[OPTN_UPDATEMICROS]) updatemicros = *((long *)options[OPTN_UPDATEMICROS]);
  263.                 if (options[OPTN_TOP]) top = *((long *)options[OPTN_TOP]);
  264.                 if (options[OPTN_LEFT]) left = *((long *)options[OPTN_LEFT]);
  265.                 if (options[OPTN_PRIORITY]) priority = *((long *)options[OPTN_PRIORITY]);
  266.                 rc = 0;
  267.                 }
  268.             else {
  269.                 /*
  270.                  *  error parsing args
  271.                  */
  272.                 PrintFault(IoErr(), NULL);
  273.                 }
  274.             }
  275.  
  276.         else if (IconBase = myopenlibrary(ICONNAME, 37l)) {
  277.  
  278.             BPTR olddir = -1l;
  279.             char **tooltypesarray;
  280.             char *tooltype;
  281.             struct WBArg *wbarg;
  282.  
  283.             if (wbarg = &(WBenchMsg->sm_ArgList)[WBenchMsg->sm_NumArgs - 1l]) {
  284.  
  285.                 if (wbarg->wa_Name) {
  286.  
  287.                     if (wbarg->wa_Lock) olddir = CurrentDir(wbarg->wa_Lock);
  288.  
  289.                     if (diskobj = GetDiskObject(wbarg->wa_Name)) {
  290.  
  291.                         tooltypesarray = diskobj->do_ToolTypes;
  292.  
  293.                         if (tooltype = FindToolType(tooltypesarray, OPTION_FORMAT)) FORMAT = (long)tooltype;
  294.                         if (tooltype = FindToolType(tooltypesarray, OPTION_UPDATESECONDS)) updateseconds = atol(tooltype);
  295.                         if (tooltype = FindToolType(tooltypesarray, OPTION_UPDATEMICROS)) updatemicros = atol(tooltype);
  296.                         if (FindToolType(tooltypesarray, OPTION_WINDOWTOFRONT)) WINDOWTOFRONT = TRUE;
  297.                         if (tooltype = FindToolType(tooltypesarray, OPTION_LEFT)) left = atol(tooltype);
  298.                         if (tooltype = FindToolType(tooltypesarray, OPTION_TOP)) top = atol(tooltype);
  299.                         if (tooltype = FindToolType(tooltypesarray, OPTION_PRIORITY)) priority = atol(tooltype);
  300.                         if (tooltype = FindToolType(tooltypesarray, OPTION_PUBSCREEN)) PUBSCREEN = (long)tooltype;
  301.                         rc = 0;
  302.  
  303.                         } /* if diskobj */
  304.  
  305.                     if (olddir != -1l) CurrentDir(olddir);
  306.  
  307.                     } /* if wbarg->wa_Name */
  308.  
  309.                 } /* if wbarg */
  310.  
  311.             } /* if WBenchMsg && IconBase */
  312.  
  313.         if (!rc && !CheckSignal(SIGBREAKF_CTRL_C) && (GfxBase = myopenlibrary("graphics.library", 37l))) {
  314.  
  315.             rc = RETURN_FAIL;
  316.  
  317.             if (mytask = FindTask(NULL)) {
  318.  
  319.                 if (LocaleBase = myopenlibrary("locale.library", 38l)) {
  320.  
  321.                     if (locale = OpenLocale(NULL)) {
  322.  
  323.                         if (!FORMAT) FORMAT = (long)locale->loc_ShortDateTimeFormat;
  324.  
  325.                         if (timerport = CreateMsgPort()) {
  326.  
  327.                             if (timereq = CreateIORequest(timerport, sizeof(struct timerequest))) {
  328.  
  329.                                 if (!OpenDevice(TIMERNAME, UNIT_VBLANK, (struct IORequest *)timereq, 0l)) {
  330.  
  331.                                     if (scr = LockPubScreen((UBYTE *)PUBSCREEN)) {
  332.  
  333.                                         DateStamp(&datestamp);
  334.                                         bufferpos = 0;
  335.                                         FormatDate(locale, (STRPTR)FORMAT, &datestamp, &putcharhook);
  336.  
  337.                                         mywindowtags[P_WA_Width].ti_Data = (ULONG)(TextLength(&scr->RastPort, buffer, strlen(buffer)) + WIDTH_OF_CLOSE_GADGET + 20);
  338.                                         if (left != -1) mywindowtags[P_WA_Left].ti_Data = left;
  339.                                         else mywindowtags[P_WA_Left].ti_Data = (ULONG)(scr->Width - mywindowtags[P_WA_Width].ti_Data - WIDTH_OF_DEPTH_GADGET);
  340.                                         if (top != -1) mywindowtags[P_WA_Top].ti_Data = top;
  341.                                         mywindowtags[P_WA_Height].ti_Data = (ULONG)(scr->BarHeight + 1);
  342.                                         mywindowtags[P_WA_PubScreen].ti_Data = (ULONG)scr;
  343.  
  344.                                         if (win = OpenWindowTagList(NULL, mywindowtags)) {
  345.  
  346.                                             timereq->tr_node.io_Command = TR_ADDREQUEST;
  347.                                             timereq->tr_time.tv_secs = 0l;
  348.                                             timereq->tr_time.tv_micro = 10l;
  349.                                             SendIO(&(timereq->tr_node));
  350.  
  351.                                             startpri = SetTaskPri(mytask, priority);
  352.  
  353.                                             getmessages(win);
  354.  
  355.                                             SetTaskPri(mytask, (long)startpri);
  356.  
  357.                                             CloseWindow(win);
  358.  
  359.                                             rc = 0;
  360.  
  361.                                             }
  362.  
  363.                                         UnlockPubScreen(NULL, scr);
  364.                                         }
  365.  
  366.                                     CloseDevice((struct IORequest *)timereq);
  367.  
  368.                                     } /* if OpenDevice() */
  369.  
  370.                                 else request(MSG_ATTENTION, RESUME_GADGETS, MSG_ERROR_LIBRARY, TIMERNAME, 0);
  371.  
  372.                                 DeleteIORequest(timereq);
  373.  
  374.                                 } /* if timereq = CreateIORequest() */
  375.  
  376.                             DeleteMsgPort((struct MsgPort *)timerport);
  377.  
  378.                             } /* if timerport */
  379.  
  380.                         else request(MSG_ATTENTION, RESUME_GADGETS, MSG_ERROR_OPENPORT);
  381.  
  382.                         CloseLocale(locale);
  383.  
  384.                         }
  385.  
  386.                     CloseLibrary(LocaleBase);
  387.  
  388.                     }
  389.  
  390.                 } /* if mytask */
  391.  
  392.             CloseLibrary(GfxBase);
  393.  
  394.             } /* if GfxBase */
  395.  
  396.         if (!WBenchMsg) {
  397.             if (args) FreeArgs(args);
  398.             }
  399.         else {
  400.             if (diskobj) FreeDiskObject(diskobj);
  401.             if (IconBase) CloseLibrary(IconBase);
  402.             }
  403.  
  404.         CloseLibrary((struct Library *)IntuitionBase);
  405.  
  406.         } /* if IntutionBase */
  407.  
  408.     _exit(rc);
  409. }
  410.  
  411. void __saveds __asm putcharfunc(register __a0 struct Hook *h, register __a2 void *object, register __a1 char c)
  412. {
  413.     if (bufferpos < BUFFERSIZE) ((char *)h->h_Data)[bufferpos++] = c;
  414. }
  415.  
  416. void getmessages(struct Window *win)
  417. {
  418.     struct IntuiMessage *msg;
  419.     unsigned long sigreceived;
  420.     unsigned long idcmpsigflag = 1 << win->UserPort->mp_SigBit;
  421.     unsigned long timersigflag = 1 << timerport->mp_SigBit;
  422.     unsigned long sigstowaitfor = SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_F | idcmpsigflag | timersigflag;
  423.     unsigned short quit = FALSE;
  424.  
  425.     while (!quit) {
  426.  
  427.         sigreceived = Wait(sigstowaitfor);
  428.  
  429.         if (sigreceived & timersigflag) {
  430.             /*
  431.              *  signal at timerport
  432.              */
  433.             if (GetMsg(timerport) == (struct Message *)timereq) {
  434.                 /*
  435.                  *  arrived any message ?
  436.                  */
  437.                 timereq->tr_time.tv_secs = updateseconds;
  438.                 timereq->tr_time.tv_micro = updatemicros;
  439.                 SendIO(&(timereq->tr_node));
  440.  
  441.                 DateStamp(&datestamp);
  442.                 bufferpos = 0;
  443.                 FormatDate(locale, (STRPTR)FORMAT, &datestamp, &putcharhook);
  444.                 SetWindowTitles(win, buffer, (UBYTE*)~0);
  445.                 if (WINDOWTOFRONT && (IntuitionBase->FirstScreen == win->WScreen)) WindowToFront(win);
  446.                 }
  447.             }
  448.  
  449.         if (sigreceived & idcmpsigflag) {
  450.  
  451.             while ((msg = (struct IntuiMessage *)GetMsg(win->UserPort)) && !quit) {
  452.                 /*
  453.                  *  check and free message
  454.                  */
  455.                 if (msg->Class == CLOSEWINDOW) quit = TRUE;
  456.                 ReplyMsg((struct Message *)msg);
  457.                 } /* while msg */
  458.  
  459.             }
  460.  
  461.         if (sigreceived & SIGBREAKF_CTRL_C) quit = TRUE;
  462.         if (sigreceived & SIGBREAKF_CTRL_F) WindowToFront(win);
  463.  
  464.         } /* while !quit */
  465.  
  466.     /*
  467.      *  cancel pending IORequest
  468.      */
  469.     AbortIO(&(timereq->tr_node));
  470.     WaitIO((struct IORequest *)timereq);
  471.  
  472. }
  473.